<?php

namespace Xrfg\Api\Trading\Home\Repositories;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Xrfg\Core\Trading\Spot\Models\Kline;

/**
 * Class CoinPriceRepository.
 */
class CoinPriceRepository
{
    public function __construct()
    {
    }

    /**
     * 币种转成USDT.
     */
    public function coinToUsdt($coin_name)
    {
        bcscale(8);

        // 币种转化为美元的价格
        $price = 0;
        if ('USDT' == $coin_name) {
            $price = 1;
        } else {
            // 1.通过USDT交易区转化
            try {
                /** @var Coin $this */
                $symbol = $coin_name.'/USDT';
                if (in_array($symbol, array_keys(config('huobi')))) { // 取火币数据
                    $price = $this->getHuobiPrice($symbol);
                } else {
                    $price = (new Kline($symbol, 1))
                        ->orderBy('time_open', 'desc')
                        ->value('price_close') ?: '0.00000000';
                }
            } catch (\Exception $exception) {
                // 2.通过ETH交易区转化
                try {
                    if ('ETH' == $coin_name) {
                        throw new \Exception('ETH/ETH交易对不存在');
                    }
                    /** @var Coin $this */
                    $symbol = $coin_name.'/ETH';
                    if (in_array($symbol, array_keys(config('huobi')))) { // 取火币数据
                        $close = $this->getHuobiPrice($symbol);
                    } else {
                        $close = (new Kline($symbol, 1))
                            ->orderBy('time_open', 'desc')
                            ->value('price_close') ?: '0.00000000';
                    }
                    // ETH转化为USDT
                    if (in_array('ETH/USDT', array_keys(config('huobi')))) { // 取火币数据
                        $eth_usdt = $this->getHuobiPrice('ETH/USDT');
                    } else {
                        $eth_usdt = (new Kline('ETH/USDT', 1))
                            ->orderBy('time_open', 'desc')
                            ->value('price_close') ?: '0.00000000';
                    }
                    $price = bcmul($close, $eth_usdt);
                } catch (\Exception $exception) {
                    // 3.通过ET交易区转化
                    try {
                        if ('ET' == $coin_name) {
                            throw new \Exception('ET/ET交易对不存在');
                        }
                        /** @var Coin $this */
                        $symbol = $coin_name.'/ET';
                        if (in_array($symbol, array_keys(config('huobi')))) { // 取火币数据
                            $close = $this->getHuobiPrice($symbol);
                        } else {
                            $close = (new Kline($symbol, 1))
                                ->orderBy('time_open', 'desc')
                                ->value('price_close') ?: '0.00000000';
                        }
                        // ET转化为USDT
                        if (in_array('ET/USDT', array_keys(config('huobi')))) { // 取火币数据
                            $et_usdt = $this->getHuobiPrice('ET/USDT');
                        } else {
                            $et_usdt = (new Kline('ET/USDT', 1))
                                ->orderBy('time_open', 'desc')
                                ->value('price_close') ?: '0.00000000';
                        }
                        $price = bcmul($close, $et_usdt);
                    } catch (\Exception $exception) {
                        \Log::debug('计算'.$coin_name.'对USDT价格，在USDT，ETH，ET交易区都没有匹配到交易对');
                    }
                }
            }
        }

        return $price;
    }

    /**
     * 取火币价格.
     *
     * @param $symbol 交易对名称
     *
     * @return string
     */
    public function getHuobiPrice($symbol)
    {
        $symbol = strtolower(str_replace('/', '', $symbol));
        $redis = Redis::connection();
        $ticker = $redis->get('huobi:ticker:'.$symbol);
        if (!$ticker) {
            return '0.00000000';
        } else {
            $ticker = json_decode($ticker, true);

            return $ticker['close'];
        }
    }

    /**
     * 获取法币市场价格.
     *
     * @param $coin_name
     *
     * @return int|mixed|string
     */
    public function getOtcMarketPrice($coin_name)
    {
        return Cache::get('ticker:okex.com:otc:'.strtolower($coin_name))['price_cny'];
    }
}
